using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using TVDesigner.Entities.Elements;
using TVDesigner.GUI.Controls;

namespace TVDesigner.GUI.Elements
{
    //public delegate void MyEventHandler(object sender, MyEventArgs e);
    //public class MyEventArgs: EventArgs
    //{
      
    //}

    public partial class Element : UserControl
    {
        private bool _IsDragging;

        private int _ClickOffsetX;
        private int _ClickOffsetY;

        protected Control _FocusControl;

        protected GenericComponent _LogicElement;

        //public event MyEventHandler MyEvent;
        //protected virtual void OnMyEvent(MyEventArgs e)
        //{
        //    MyEvent(this, e);
        //}


        public Control FocusControl
        {
            get { return _FocusControl; }
            set { _FocusControl = value; }
        }
        public GenericComponent LogicElement
        {
            get { return _LogicElement; }
            set { _LogicElement = value; }
        }

        public bool IsDragging
        {
            get { return _IsDragging; }
            set { _IsDragging = value; }
        }

        public Element()
        {
            InitializeComponent();
        }

        protected void AddEvents(Control control)
        {
            _FocusControl = control;

            _FocusControl.MouseLeave += new System.EventHandler(Element_MouseLeave);
            _FocusControl.MouseMove += new System.Windows.Forms.MouseEventHandler(Element_MouseMove);
            _FocusControl.MouseDown += new System.Windows.Forms.MouseEventHandler(Element_MouseDown);
            _FocusControl.MouseUp += new System.Windows.Forms.MouseEventHandler(Element_MouseUp);
            _FocusControl.MouseEnter += new System.EventHandler(Element_MouseEnter);

            _FocusControl.KeyUp += new System.Windows.Forms.KeyEventHandler(Element_KeyUp);
        }

        public void AddClickEvent(MouseEventHandler eventHandler)
        {
            _FocusControl.MouseDown += eventHandler;
        }

        protected void Element_MouseEnter(object sender, EventArgs e)
        {
            this.BorderStyle = BorderStyle.FixedSingle;
            this.Cursor = Cursors.Hand;
        }

        protected void Element_MouseLeave(object sender, EventArgs e)
        {
            this.BorderStyle = BorderStyle.None;
        }

        protected void Element_MouseDown(object sender, MouseEventArgs e)
        {
            _FocusControl.Focus();
            this.BringToFront();
            _IsDragging = true;
            _ClickOffsetX = e.X;
            _ClickOffsetY = e.Y;
            this.Parent.Invalidate();
        }

        protected void Element_MouseUp(object sender, MouseEventArgs e)
        {
            _IsDragging = false;
            this.BringToFront();
            this.Parent.Invalidate();
        }

        protected void Element_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_IsDragging)
                return;

            this.Left += e.X - _ClickOffsetX;
            this.Top += e.Y - _ClickOffsetY;

            _LogicElement.Location = new Point(this.Left, this.Top);
            this.Parent.Invalidate();
        }


        #region Validacao da Propriedades

        public virtual void PropertyGridValueChanged(PropertyGrid propertyGrid, PropertyValueChangedEventArgs e)
        {
            if (e.ChangedItem.Label == "Width" && !_ValidateWidth((int)e.ChangedItem.Value))
            {
                e.ChangedItem.PropertyDescriptor.SetValue(
                    propertyGrid.SelectedObject, e.OldValue);
            }
            else if (e.ChangedItem.Label == "Height" && !_ValidateHeight((int)e.ChangedItem.Value))
            {
                e.ChangedItem.PropertyDescriptor.SetValue(
                    propertyGrid.SelectedObject, e.OldValue);
            }
            else if (e.ChangedItem.Label == "Size" && !_ValidateSize((Size)e.ChangedItem.Value))
            {
                e.ChangedItem.PropertyDescriptor.SetValue(
                    propertyGrid.SelectedObject, e.OldValue);
            }
            else if (e.ChangedItem.Label == "Name" && !_ValidateName((string)e.ChangedItem.Value))
            {
                e.ChangedItem.PropertyDescriptor.SetValue(
                    propertyGrid.SelectedObject, e.OldValue);
            }
            else if (e.ChangedItem.Label == "Visible" && !_ValidateVisible((bool)e.ChangedItem.Value))
            {
                e.ChangedItem.PropertyDescriptor.SetValue(
                    propertyGrid.SelectedObject, e.OldValue);
            }
            else if (e.ChangedItem.Label == "Location")
            {
                this.Location = (Point)e.ChangedItem.Value;
            }
            //else if (e.ChangedItem.Label == "X" && !_ValidateX((int)e.ChangedItem.Value))
            //{
            //    e.ChangedItem.PropertyDescriptor.SetValue(
            //        propertyGrid.SelectedObject, e.OldValue);
            //}
            //else if (e.ChangedItem.Label == "Y" && !_ValidateY((int)e.ChangedItem.Value))
            //{
            //    e.ChangedItem.PropertyDescriptor.SetValue(
            //        propertyGrid.SelectedObject, e.OldValue);
            //}
        }

        private bool _ValidateVisible(bool visible)
        {
            bool valid = true;
            _LogicElement.Visible = visible;
            return valid;
        }

        private bool _ValidateName(string name)
        {
            bool valid = true;
            if (name.IndexOf(" ") >= 0)
            {
                valid = false;
            }
            else
            {
                _LogicElement.Name = name;
            }
            return valid;
        }

        protected virtual bool _ValidateSize(Size newSize)
        {
            bool valid = true;
            if (newSize.Height <= 0 || newSize.Width <= 0)
                valid = false;
            else
                this.Size = newSize;
            return valid;
        }

        private bool _ValidateX(int newX)
        {
            bool valid = true;
            if (newX < 0)
                valid = false;
            else
                this.Location = new Point(newX, this.Location.Y);

            return valid;
        }

        private bool _ValidateY(int newY)
        {
            bool valid = true;
            if (newY < 0)
                valid = false;
            else
                this.Location = new Point(this.Location.X, newY);

            return valid;
        }

        private bool _ValidateWidth(int newWidth)
        {
            bool valid = true;
            if (newWidth < 0)
                valid = false;
            else
                this.Size = new Size(newWidth, this.Height);

            return valid;
        }

        private bool _ValidateHeight(int newHeight)
        {
            bool valid = true;
            if (newHeight < 0)
                valid = false;
            else
                this.Size = new Size(this.Width, newHeight);

            return valid;
        } 
        #endregion

        protected void Element_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                _RemoveElement();
            }
        }

        protected virtual void _RemoveElement()
        {
            DesignPanel panel = this.Parent.Parent as DesignPanel;
            panel.RemoveElement(this);
        }
    }
}
